Oxlint の Type-Aware Linting について何もわからんので色々読む
まずはこれから読むぞ
Rust-Based JavaScript Linters: Fast, But No Typed Linting Right Now | Goldblog
Rust 製の ESLint 互換 JavaScript, TypeScript linter がたくさんあるけど、どれも ESLint そのものだけを置き換えるようなものだったらしい
typescript-eslint のような linting with type information(Type-Checked Linting) のようなことはできていなかった
c.f. https://typescript-eslint.io/getting-started/typed-linting/
Type-Checked Linting にも課題があって、それはパフォーマンス
型情報を使用するのでプロジェクト全体の見る必要がある
tsc よりも時間がかかるなんてことも
(tsgo が出たおかげで 10x faster になったけど)
つまり、Rust 製の linter はどれもそれ自身と typescript-eslint を併用する必要があった
型情報が必要ないところは爆速で、型情報が必要な部分は typescript-eslint に任せる感じ
TypeScript は TypeScript で書かれているので、JavaScript 実行スピードが律速になっている
Rust 製 linter が Type-Checked Linting を実現するためには以下のどれかが必要
JavaScript の速度しか出ない TypeScript 純正 API を呼び出すことによるパフォーマンスの低下(ヒット)を受け入れる
TypeScript のAPI をネイティブ速度が出る言語で再実装する(!)
TypeScript のAPIそのものをネイティブ並みの速度まで高速化する
もう一つの大局的な戦略として TypeScript の Language Server に linting を統合するという方法もある
tsslint とかがそれをやろうと試みている
GitHub - johnsoncodehk/tsslint: 🔋⚡️ The fastest and lightest TypeScript semantic linting solution
Language Server への統合は希望溢れるけど、数年を要するような長期的なものになりそうとのこと
次はこれ
Oxlint Type-Aware Preview | The JavaScript Oxidation Compiler
Oxlint で type-aware linting ができるようになるぞ!(preview release)って記事(20250817 公開)
待望の no-floating-promises ルールとか関連ルールについても載ってるらしい
oxlint-tsgolint ってのもあるみたい
GitHub - oxc-project/tsgolint: Type aware linting for oxlint
というかこれが type-aware linting の実現のコア
元々 TypeScript チームの方で typescript/tsgolint の prototype をやってたらしいけど、
GitHub - typescript-eslint/tsgolint: ✨ Experimental proof-of-concept typescript-go powered JS/TS linter written in Go
開発リソースを割かないと決めたらしく typescript-eslint の方でやってくことにした
Boshen さんが auvred さんに fork の連絡をして Oxlint 用の縮小スコープバージョンを適用した
このバージョンでは linter が必要とする洗練された設定解決を含まない type-aware ルールだけ含んでいる
auvred さんが Oxc organization 下でやることを提案してくれた
アーキテクチャとしては
Oxlint written in Rust
tsgolint written in Go
で、Oxlint が tsgolint の "frontend" を担う
CLI handling、path traversal, ignore logic, diagnostic printing を Oxlint が担う
code:text
oxlint CLI (returns paths + rules + configuration)
-> tsgolint (returns diagnostics)
-> oxlint CLI (prints diagnostics)
tsgolint は tsgo とは公開 API では communicate しない
代わりに内部 API に "shim" してこじ開けて tsgo をコンパイルしている(!)
type-aware ルールはすべてこのこじ開けられた API を直接利用している
syumai さんの発表スライドで "shim" について解説されている
tsgolintはいかにしてtypescript-goの非公開APIを呼び出しているのか - Speaker Deck
推奨されたことじゃないけど動いた!
While this isn't the recommended approach for accessing internals, it works!
Oxc では独自のタイプチェッカーの実装は諦めた
Boshen さんが挑戦したやつだったり
ezno のやつだったり
stc だったり
...
Biome は ver 2.0 に向けて独自のタイプチェッカーをやってるらしい
Oxc では自前でそこやるのは実現可能なことじゃないと判断した
(TypeScript は変化が激しいため)
tsgo 以前は TypeScript の AST を estree にしたり、直接走査したりすることで TypeScript の公開 API への plugin interface を追加していた
typescript-estlint
tsslint
tsl
Oxc でも Oxlint によってプロセス間通信(IPC)を検討してたけどこれも断念
tsgo ではプロセス間通信(IPC)によって TypeScript の AST をエンコードして、JavaScript 側でデコードする方向に寄ってっている
これらの方法でも機能するけど以下を伴う
Oxlint が求めるスピードにパフォーマンスの課題が見合わない
TypeScript の AST とのマッピングのある AST をメンテするコスト
tsgolint がパフォーマンスの課題について解決するけどそれでも依然として技術的な挑戦がある
1 つは TypeScript のバージョン変更を余儀なくされる制約があること
Oxc では tsgo のスナップショットをリリースして、TypeScript のバージョンと合わせることを計画していた
これによって TypeScript のバージョンに合った oxlint-tsgolint のバージョンをインストールできる
次に tsgolint のメンテコストがある
TypeScript の内部 API を shim するのはリスクがある
しかし TypeScript の AST とそれらを見に来る人(visitor の上手い訳がわからない)は非常に安定している
このリスクを許容して tsgo の破壊的変更の際には修正することに決めたそう
当時の tsgolint にはパフォーマンス上の課題があって、巨大な(数百プロジェクトとかの) monorepo プロジェクトだとうまく動かない
バグに遭遇するとデッドロックになったりOOM(out of memory)になったりする
tsgolint の v1.0 のリリースに向けて以下を頑張っている
巨大 monorepo プロジェクトのパフォーマンス問題
個人的ルールを設定可能
個人的ルールの確かさ
IDE サポート
全体的な安全さ
で次にこれ
Type-Aware Linting Alpha | The JavaScript Oxidation Compiler
この Alpha のマイルストーンで安定性、設定可能性、ルールのカバレッジがめちゃ改善された
no-floating-promises, no-misused-promises, await-thenable など TypeScript の型情報を活用した強力な lint ルールがある
これらを含む 43 個の type-aware lint ルールが使用可能!
しかし Oxlint Type-Aware Preview | The JavaScript Oxidation Compiler に書いてあった巨大 monorepo プロジェクトの課題は依然として残っているらしい